package ntd.util.modular.data.util.handle.tool;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import ntd.tool.ToolId;
import ntd.util.util.ToolDuration;

import java.util.*;

/**
 * map - set 类型封装
 * @author: liuwenju
 * @date: 2023/9/12 11:31
 * @version: 1.0
 */
public class LJMapSet<T> {

    // 数据存储
    private Map<String, Set<T>> mapSet = new HashMap<>();

    /**
     * 根据值查找键列表
     * @param val
     * @return
     */
    public Set<String> getKeyByVal(T val) {
        Set<String> keys = new HashSet<>();
        for (Map.Entry<String, Set<T>> entry : mapSet.entrySet()) {
            for (T t : entry.getValue()) {
                if (t.equals(val)) {
                    keys.add(entry.getKey());
                }
            }
        }
        return keys;
    }

    /**
     * 根据值获取键，单个
     * @param val
     * @return
     */
    public String getOneKeyByVal(T val) {
        for (Map.Entry<String, Set<T>> entry : mapSet.entrySet()) {
            for (T t : entry.getValue()) {
                if (t.equals(val)) {
                    return entry.getKey();
                }
            }
        }
        return null;
    }

    /**
     * 添加值
     * @param key
     * @param val
     */
    public void put(String key, T val) {
        if (StrUtil.isBlank(key) || ObjectUtil.isNull(val)) {
            return;
        }
        set(key).add(val);
    }

    /**
     * 获取值
     * @param key
     * @return
     */
    public Set<T> get(String key) {
        if (StrUtil.isBlank(key)) {
            return new HashSet<>();
        }
        return set(key);
    }

    /**
     * 删除某个元素
     * @param key
     * @param val
     */
    public void del(String key, T val) {
        if (StrUtil.isBlank(key) || ObjectUtil.isNull(val)) {
            return;
        }
        set(key).remove(val);
    }

    /**
     * 清空元素值
     * @param key
     */
    public void clear(String key) {
        if (StrUtil.isBlank(key)) {
            return;
        }
        set(key).clear();
    }

    /**
     * 获取set逻辑，没有的话自动创建
     * @param key
     * @return
     */
    private Set<T> set(String key) {
        Set<T> vals = mapSet.get(key);
        if (ObjectUtil.isNull(vals)) {
            vals = new HashSet<>();
            mapSet.put(key, vals);
        }
        return vals;
    }

    public static void main(String[] args) {
        LJMapSet<String> ljMapSet = new LJMapSet<>();

        for (int i = 0; i < 1000000; i++) {
            ljMapSet.put("mn234" + i, "123458" + ToolId.genId());
        }

        ljMapSet.put("mn", "123456");
        ljMapSet.put("mn", "123456");
        ljMapSet.put("mn", "1234567");
        ljMapSet.put("mn", "123458");

        StaticLog.info(JSONUtil.toJsonStr(ljMapSet.get("mn")));
        ljMapSet.del("mn", "123458");
        StaticLog.info(JSONUtil.toJsonStr(ljMapSet.get("mn")));

        ToolDuration.duration(() -> {
            StaticLog.info(ljMapSet.getOneKeyByVal("123456sdf"));
        });

        ljMapSet.clear("mn");
        StaticLog.info(JSONUtil.toJsonStr(ljMapSet.get("mn")));
    }

}
